import {
  ChangeDetectionStrategy,
  Component,
  Input,
  ViewEncapsulation,
  OnInit,
  ElementRef,
  NgZone,
  OnDestroy,
  AfterViewInit,
} from '@angular/core';
import { fromEvent, Subject } from 'rxjs';
import { takeUntil } from 'rxjs/operators';
import { LvConfig } from '../core/config';
import { I18NService } from '../core/i18n/api';
import { InputBoolean } from '../core/utils/convert';

@Component({
  selector: '[lv-button]',
  templateUrl: './button.component.html',
  changeDetection: ChangeDetectionStrategy.OnPush,
  encapsulation: ViewEncapsulation.None,
  host: {
    '[class.lv-button]': 'true',
    '[class.lv-button-type-primary]': "lvType === 'primary'",
    '[class.lv-button-type-default]': "lvType === 'default'",
    '[class.lv-button-type-link]': "lvType === 'link'",
    '[class.lv-button-size-large]': "lvSize === 'large'",
    '[class.lv-button-size-small]': "lvSize === 'small'",
    '[class.lv-button-size-default]': "lvSize === 'default'",
    '[class.lv-button-size-auto]': "lvSize === 'auto'",
    '[class.lv-button-loading]': 'lvLoading',
    '[class.lv-button-dangerous]': 'lvDanger',
  },
})
export class ButtonComponent implements OnInit, AfterViewInit, OnDestroy {
  @Input() lvLoadingText: string;

  @Input() @InputBoolean() lvDanger: boolean = false;

  @Input() @InputBoolean() lvLoading: boolean = false;

  @Input() lvType: 'primary' | 'link' | 'default' = 'default';

  @Input() lvSize: 'large' | 'default' | 'small' | 'auto' = 'default';

  loadingSrc: string;

  private destroy$ = new Subject<void>();
  constructor(
    private i18n: I18NService,
    private ngZone: NgZone,
    private elementRef: ElementRef,
  ) {}

  ngOnDestroy(): void {
    this.destroy$.next();
    this.destroy$.complete();
  }

  ngAfterViewInit(): void {
    const timer = setTimeout((): void => {
      clearTimeout(timer);
      this.elementRef.nativeElement.style.transitionProperty = 'border, background-color, box-shadow, opacity, color';
    });
  }

  ngOnInit(): void {
    if (this.lvType === 'primary') {
      this.loadingSrc = 'assets/webp/white.png';
    } else if (this.lvType === 'link') {
      this.loadingSrc = this.lvDanger ? 'assets/webp/gray.png' : 'assets/webp/blue.png';
    } else {
      this.loadingSrc = 'assets/webp/gray.png';
    }

    this.loadingSrc = `${LvConfig.assetsPrefixPath}${this.loadingSrc}`;

    this.ngZone.runOutsideAngular((): void => {
      fromEvent<MouseEvent>(this.elementRef.nativeElement, 'click', { capture: true })
        .pipe(takeUntil(this.destroy$))
        .subscribe((event): void => {
          if (this.lvLoading) {
            event.preventDefault();
            event.stopImmediatePropagation();
          }
        });
    });
  }
}
